// Copyright 2011 George Cook
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#import "BaseTest.h"
#import "Injective.h"
#import "InjectiveContextXMLFactory.h"
#import "InjectiveObjectDescription.h"
#import "InjectivePropertyDescription.h"
#import "InjectivePropertyValueDescription.h"
#import "InjectiveDictionaryPropertyValueDescription.h"

@interface InjectiveDictionaryPropertyValueXMLFactoryTest : BaseTest
{
	InjectiveContextXMLFactory *factory;
}
@end


@implementation InjectiveDictionaryPropertyValueXMLFactoryTest
- (void)setUp
{
	factory = [[InjectiveContextXMLFactory alloc] init];
}

- (void)tearDown
{
	[factory release], factory = nil;
}

- (void)testDictionaryValue
{
	NSArray *descriptions = [factory processXMLFile:@"testDictionaryValue.xml"];
	GHAssertNotNil(descriptions, @"no descriptions were generated");
	InjectiveObjectDescription *description = [descriptions lastObject];
	GHAssertNotNil(description.propertyDescriptions, @"there were no property descriptions");
	GHAssertTrue(1 == description.propertyDescriptions.count, @"didn't create 1 property, created %d", description.propertyDescriptions.count);
	InjectivePropertyDescription *propertyDescription = [description.propertyDescriptions lastObject];
	GHAssertTrue([propertyDescription.type isEqualToString:@"Dictionary"],@"didn't detect correct type");
	GHAssertTrue([propertyDescription.propertyName isEqualToString:@"dictionaryValue"],@"didn't detect correct property name");
	InjectiveDictionaryPropertyValueDescription *dictionaryDescription = (InjectiveDictionaryPropertyValueDescription *)propertyDescription.value;
	GHAssertNotNil(dictionaryDescription,@"value wasn't set");
	GHAssertTrue(dictionaryDescription.class == [InjectiveDictionaryPropertyValueDescription class],@"was not an dictionary class");
	GHAssertNil(dictionaryDescription.propertyValueText,@"text is not set for dictionary descriptions");
	GHAssertTrue([dictionaryDescription.type isEqualToString:@"Dictionary"],@"didn't set propertyvalue type");
	
	//check values were correctly set
	NSDictionary *values = dictionaryDescription.valueDescriptionsByName;
	GHAssertTrue(3 == values.count, @"didn't create 1 property, created %d", values.count);
	
	InjectivePropertyDescription *dictionaryValuePropertyDescription = [values objectForKey:@"numberValue"];
	InjectivePropertyValueDescription *valueDescription = dictionaryValuePropertyDescription.value;
	GHAssertNotNil(valueDescription,@"value wasn't set");
	GHAssertTrue(valueDescription.class == [InjectivePropertyValueDescription class],@"was not a primitve class");
	GHAssertTrue([valueDescription.propertyValueText isEqualToString:@"1"],@"didn't set propertyvalue text");
	GHAssertTrue([valueDescription.type isEqualToString:@"Integer"],@"didn't set propertyvalue type");
	
	dictionaryValuePropertyDescription = [values objectForKey:@"stringValue"];
	valueDescription = dictionaryValuePropertyDescription.value;
	GHAssertNotNil(valueDescription,@"value wasn't set");
	GHAssertTrue(valueDescription.class == [InjectivePropertyValueDescription class],@"was not a primitve class");
	GHAssertTrue([valueDescription.propertyValueText isEqualToString:@"some text"],@"didn't set propertyvalue text");
	GHAssertTrue([valueDescription.type isEqualToString:@"String"],@"didn't set propertyvalue type");
	
	dictionaryValuePropertyDescription = [values objectForKey:@"funkyValue"];
	GHAssertNotNil(dictionaryValuePropertyDescription,@"value wasn't set");
	GHAssertTrue([dictionaryValuePropertyDescription.type isEqualToString:@"FunkyProvider"],@"didn't set propertyvalue text");
}

- (void)testNestedDictionaryValue
{
	NSArray *descriptions = [factory processXMLFile:@"testNestedDictionaryValue.xml"];
	GHAssertNotNil(descriptions, @"no descriptions were generated");
	InjectiveObjectDescription *description = [descriptions lastObject];
	GHAssertNotNil(description.propertyDescriptions, @"there were no property descriptions");
	GHAssertTrue(1 == description.propertyDescriptions.count, @"didn't create 1 property, created %d", description.propertyDescriptions.count);
	InjectivePropertyDescription *propertyDescription = [description.propertyDescriptions lastObject];
	GHAssertTrue([propertyDescription.type isEqualToString:@"Dictionary"],@"didn't detect correct type");
	GHAssertTrue([propertyDescription.propertyName isEqualToString:@"dictionaryValue"],@"didn't detect correct property name");
	InjectiveDictionaryPropertyValueDescription *dictionaryDescription = (InjectiveDictionaryPropertyValueDescription *)propertyDescription.value;
	GHAssertNotNil(dictionaryDescription,@"value wasn't set");
	GHAssertTrue(dictionaryDescription.class == [InjectiveDictionaryPropertyValueDescription class],@"was not an dictionary class");
	GHAssertNil(dictionaryDescription.propertyValueText,@"text is not set for dictionary descriptions");
	GHAssertTrue([dictionaryDescription.type isEqualToString:@"Dictionary"],@"didn't set propertyvalue type");
	
	//check values were correctly set
	NSDictionary *values = dictionaryDescription.valueDescriptionsByName;
	GHAssertTrue(4 == values.count, @"didn't create properties, created %d", values.count);
	
	InjectivePropertyDescription *dictionaryValuePropertyDescription = [values objectForKey:@"numberValue"];
	InjectivePropertyValueDescription *valueDescription = dictionaryValuePropertyDescription.value;
	GHAssertNotNil(valueDescription,@"value wasn't set");
	GHAssertTrue(valueDescription.class == [InjectivePropertyValueDescription class],@"was not a primitve class");
	GHAssertTrue([valueDescription.propertyValueText isEqualToString:@"1"],@"didn't set propertyvalue text");
	GHAssertTrue([valueDescription.type isEqualToString:@"Integer"],@"didn't set propertyvalue type");
	
	dictionaryValuePropertyDescription = [values objectForKey:@"stringValue"];
	valueDescription = dictionaryValuePropertyDescription.value;
	GHAssertNotNil(valueDescription,@"value wasn't set");
	GHAssertTrue(valueDescription.class == [InjectivePropertyValueDescription class],@"was not a primitve class");
	GHAssertTrue([valueDescription.propertyValueText isEqualToString:@"some text"],@"didn't set propertyvalue text");
	GHAssertTrue([valueDescription.type isEqualToString:@"String"],@"didn't set propertyvalue type");
	
	dictionaryValuePropertyDescription = [values objectForKey:@"funkyValue"];
	GHAssertNotNil(dictionaryValuePropertyDescription,@"value wasn't set");
	GHAssertTrue([dictionaryValuePropertyDescription.type isEqualToString:@"FunkyProvider"],@"didn't set propertyvalue text");
	
	//check nested dictionary
	propertyDescription = [values objectForKey:@"dictionaryValue"];
	GHAssertTrue([propertyDescription.type isEqualToString:@"Dictionary"],@"didn't detect correct type");
	GHAssertTrue([propertyDescription.propertyName isEqualToString:@"dictionaryValue"],@"didn't detect correct property name");
	dictionaryDescription = (InjectiveDictionaryPropertyValueDescription *)propertyDescription.value;
	GHAssertNotNil(dictionaryDescription,@"value wasn't set");
	GHAssertTrue(dictionaryDescription.class == [InjectiveDictionaryPropertyValueDescription class],@"was not an dictionary class");
	GHAssertNil(dictionaryDescription.propertyValueText,@"text is not set for dictionary descriptions");
	GHAssertTrue([dictionaryDescription.type isEqualToString:@"Dictionary"],@"didn't set propertyvalue type");
	
	//nested dictionary properties
	values = dictionaryDescription.valueDescriptionsByName;
	GHAssertTrue(3 == values.count, @"didn't create properties, created %d", values.count);
	
	dictionaryValuePropertyDescription = [values objectForKey:@"numberValue"];
	valueDescription = dictionaryValuePropertyDescription.value;
	GHAssertNotNil(valueDescription,@"value wasn't set");
	GHAssertTrue(valueDescription.class == [InjectivePropertyValueDescription class],@"was not a primitve class");
	GHAssertTrue([valueDescription.propertyValueText isEqualToString:@"2"],@"didn't set propertyvalue text");
	GHAssertTrue([valueDescription.type isEqualToString:@"Integer"],@"didn't set propertyvalue type");
	
	dictionaryValuePropertyDescription = [values objectForKey:@"stringValue"];
	valueDescription = dictionaryValuePropertyDescription.value;
	GHAssertNotNil(valueDescription,@"value wasn't set");
	GHAssertTrue(valueDescription.class == [InjectivePropertyValueDescription class],@"was not a primitve class");
	GHAssertTrue([valueDescription.propertyValueText isEqualToString:@"some text2"],@"didn't set propertyvalue text");
	GHAssertTrue([valueDescription.type isEqualToString:@"String"],@"didn't set propertyvalue type");
	
	dictionaryValuePropertyDescription = [values objectForKey:@"funkyValue"];
	GHAssertNotNil(dictionaryValuePropertyDescription,@"value wasn't set");
	GHAssertTrue([dictionaryValuePropertyDescription.type isEqualToString:@"FunkyProvider2"],@"didn't set propertyvalue text");
	
	
}

@end
